package cn.zjutleo.village_server.controller;

import cn.zjutleo.village_server.annotation.OperationLog;
import cn.zjutleo.village_server.annotation.RequiresLogin;
import cn.zjutleo.village_server.dto.HouseRentOrderDto;
import cn.zjutleo.village_server.entity.HouseRentOrder;
import cn.zjutleo.village_server.exception.apiException.daoException.SelectException;
import cn.zjutleo.village_server.service.HouseRentService;
import cn.zjutleo.village_server.util.ThreadLocalUtil;
import cn.zjutleo.village_server.vo.HouseRentDetailVo;
import cn.zjutleo.village_server.vo.HouseRentRoughVo;
import cn.zjutleo.village_server.vo.ResponseBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author : Qin Zhenghan
 * @date : Created in 2021/9/22
 * @description: 房屋出租相关控制类
 */
@Api(tags = "房屋出租相关控制类")//修饰整个类，描述Controller的作用 swagger最外面的大标题
@RestController
/**
 * @RestController 注解相当于@ResponseBody+@Controller合在一起的作用
 * RestController使用的效果是将方法返回的对象直接在浏览器上展示成json格式.
 */
@RequestMapping("")
/**
 * @RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。
 * 这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上
 */
public class HouseRentController {

    private static final String MODULE_NAME = "房屋出租模块";

    @Resource
    private HouseRentService houseRentService;

    @ApiImplicitParam(name = "id", value = "房屋出租id", paramType = "path", dataType = "Integer")
    /**
     *     @ApiImplicitParam：用在@ApiImplicitParams注解中，指定一个请求参数的各个方面
     *         name：参数名
     *         value：参数的汉字说明、解释
     *         required：参数是否必须传
     *         paramType：参数放在哪个地方
     *             · header --> 请求参数的获取：@RequestHeader
     *             · query --> 请求参数的获取：@RequestParam
     *             · path（用于restful接口）--> 请求参数的获取：@PathVariable
     *             · body（不常用）
     *             · form（不常用）
     *         dataType：参数类型，默认String，其它值dataType="Integer"
     *         defaultValue：参数的默认值
     */
    @ApiOperation("根据id获取房屋出租详细信息")
    /**
     * @ApiOperation：用在请求的方法上，说明方法的用途、作用
     *     value="说明方法的用途、作用"
     *     notes="方法的备注说明"
     */
    @OperationLog(module = MODULE_NAME, method = "根据id获取房屋出租详细信息")
    @GetMapping("/houseRent/detail/{id}")
    //GetMapping 注解已经默认封装了@RequestMapping(method = RequestMethod.GET)
    public ResponseBean<HouseRentDetailVo> getHouseRentDetailById(@PathVariable Integer id) throws SelectException {
        HouseRentDetailVo houseRentDetailVo = houseRentService.getHouseRentDetailVoById(id);
        return new ResponseBean<>(houseRentDetailVo);
    }

    @ApiOperation("根据可选条件获取房屋出租粗略信息列表")
    @ApiImplicitParams({
            /**
             * 1. name ：参数名。
             * 2. value ： 参数的具体意义，作用。
             * 3. required ： 参数是否必填。
             * 4. dataType ：参数的数据类型。
             * 5. paramType ：查询参数类型
             */
            @ApiImplicitParam(name = "villageId", value = "所属乡村id(用于地区选择)", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "type", value = "出租类型(整租/合租/长租/短租)", paramType = "query"),
            @ApiImplicitParam(name = "minPrice", value = "价格下限", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "maxPrice", value = "价格上限", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "closest", value = "是否选择最近距离", paramType = "query", dataType = "Integer")
            /**
             * path 以地址的形式提交数据
             * query 直接跟参数完成自动映射赋值
             * body 以流的形式提交 仅支持POST
             * header 参数在request headers 里边提交
             * form 以form表单的形式提交 仅支持POST
             */
    })
    @OperationLog(module = MODULE_NAME, method = "根据可选条件获取房屋出租粗略信息列表")
    @GetMapping("/houseRent/roughList")
    public ResponseBean<List<HouseRentRoughVo>> getHouseRentRoughList(@RequestParam(value = "villageId", required = false) Integer villageId,
                                                                      /**
                                                                       *  @RequestParam是传递参数的.
                                                                       *
                                                                       * @RequestParam用于将请求参数区数据映射到功能处理方法的参数上
                                                                       */
                                                                      @RequestParam(value = "type", required = false) String type,
                                                                      @RequestParam(value = "minPrice", required = false) Integer minPrice,
                                                                      @RequestParam(value = "maxPrice", required = false) Integer maxPrice,
                                                                      @RequestParam(value = "closest", required = false) Integer closest) throws SelectException {
        List<HouseRentRoughVo> houseRentRoughVos = houseRentService.getHouseRentRoughVosByConditions(villageId, type, minPrice, maxPrice, closest);
        return new ResponseBean<>(houseRentRoughVos);
    }

    @ApiOperation("获取房屋租赁所有详细信息列表")
    @OperationLog(module = MODULE_NAME, method = "获取房屋租赁所有详细信息列表")
    @GetMapping("/api/houseRent/detailList")
    public ResponseBean<List<HouseRentDetailVo>> getHouseRentDetailList() {
        List<HouseRentDetailVo> houseRentDetailVos = houseRentService.getHouseRentDetailVos();
        return new ResponseBean<>(houseRentDetailVos);
    }

    @ApiOperation("根据可选条件查询房租租赁详细信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "minPrice", value = "价格下限", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "maxPrice", value = "价格上限", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "query", value = "模糊搜索", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "check", value = "审核状态", paramType = "query", dataType = "Integer")
    })
    @OperationLog(module = MODULE_NAME, method = "根据可选条件查询房租租赁详细信息列表")
    @GetMapping("/api/houseRent/detailListByConditions")
    public ResponseBean<List<HouseRentDetailVo>> getHouseRentDetailListByConditions(@RequestParam(value = "minPrice", required = false) Integer minPrice,
                                                                                    @RequestParam(value = "maxPrice", required = false) Integer maxPrice,
                                                                                    @RequestParam(value = "query", required = false) String query,
                                                                                    @RequestParam(value = "check", required = false) Integer check) {
        List<HouseRentDetailVo> houseRentDetailVos = houseRentService.getHouseRentDetailVosByConditions(minPrice, maxPrice, query, check);
        return new ResponseBean<>(houseRentDetailVos);
    }

    @ApiOperation("按照价格区间查询房屋租赁详细信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "minPrice", value = "价格下限", paramType = "path", dataType = "Integer"),
            @ApiImplicitParam(name = "maxPrice", value = "价格上限", paramType = "path", dataType = "Integer")
    })
    @OperationLog(module = MODULE_NAME, method = "按照价格区间查询房屋租赁详细信息列表")
    @GetMapping("/api/houseRent/detailList/{minPrice}/{maxPrice}")
    public ResponseBean<List<HouseRentDetailVo>> getHouseRentDetailList(@PathVariable Integer minPrice, @PathVariable Integer maxPrice) {
        List<HouseRentDetailVo> houseRentDetailVos = houseRentService.selectHouseRentDetailVosByPrice(minPrice, maxPrice);
        return new ResponseBean<>(houseRentDetailVos);
    }

    @ApiOperation("根据描述模糊查询房屋租赁详细信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "query", value = "房屋租赁描述内容", paramType = "path", dataType = "String")
    })
    @OperationLog(module = MODULE_NAME, method = "根据描述模糊查询房屋租赁详细信息列表")
    @GetMapping("/api/houseRent/fuzzySearch/{query}")
    public ResponseBean<List<HouseRentDetailVo>> getHouseRentDetailVosByFuzzyIntro(@PathVariable String query) {
        List<HouseRentDetailVo> houseRentDetailVos = houseRentService.selectHouseRentDetailVosByFuzzyIntro(query);
        return new ResponseBean<>(houseRentDetailVos);
    }

    @ApiOperation("根据id与状态参数修改房屋租赁审核状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rentId", value = "房屋租赁id", paramType = "path", dataType = "Integer"),
            @ApiImplicitParam(name = "status", value = "目标审核状态参数(0:未审核, 1:通过, 2:未通过)", paramType = "path", dataType = "Integer")
    })
    @OperationLog(module = MODULE_NAME, method = "根据id与状态参数修改房屋租赁审核状态")
    @GetMapping("/api/houseRent/changeCheck/{rentId}/{status}")
    public ResponseBean<Object> changeHouseRentStatus(@PathVariable Integer rentId, @PathVariable Integer status) {
        houseRentService.changeHouseRentCheckStatus(rentId, status);
        return new ResponseBean<>(null);
    }

    @ApiOperation("添加房屋预约信息")
    @OperationLog(module = MODULE_NAME, method = "添加房屋预约信息")
    @RequiresLogin()
    @PostMapping("/houseRent/order/add")
    public ResponseBean<Integer> addHouseRentOrder(@RequestBody HouseRentOrderDto houseRentOrderDto) throws SelectException {
        Integer userId = ThreadLocalUtil.getCurrentUser();
        Integer orderId = houseRentService.addHouseRentOrder(houseRentOrderDto, userId);
        return new ResponseBean<>(orderId);
    }

    @ApiOperation("获取所有房屋租赁订单")
    @OperationLog(module = MODULE_NAME, method = "获取所有房屋租赁订单")
    @GetMapping("/api/houseRent/order/all")
    public ResponseBean<List<HouseRentOrder>> getAllHouseRentOrder() {
        List<HouseRentOrder> houseRentOrders = houseRentService.getAllHouseRentOrder();
        return new ResponseBean<>(houseRentOrders);
    }

    @ApiOperation("根据房屋租赁订单号查询房屋租赁详细信息")
    @OperationLog(module = MODULE_NAME, method = "根据房屋租赁订单号查询房屋租赁详细信息")
    @GetMapping("/api/houseRent/detail/{orderId}")
    public ResponseBean<HouseRentDetailVo> getHouseRentDetailVoByOrderId(@PathVariable Integer orderId) {
        HouseRentDetailVo houseRentDetailVo = houseRentService.getHouseRentDetailVoByOrderId(orderId);
        return new ResponseBean<>(houseRentDetailVo);
    }
}
